package yagwl.client.widget;

import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * Panel with a header and body. Two levels of nesting supported: level 1 and
 * level 2.
 * <p>
 * <b>CSS styles</b><br>
 * .ya-section-level1 - level 1 section<br>
 * .ya-section-level1-header - level 1 section header<br>
 * .ya-section-level1 .header - level 1 collapsible section header<br>
 * .ya-section-level2 - level 2 section<br>
 * .ya-section-level2-header - level 2 section header<br>
 * .ya-section-level2 .header - level 2 collapsible section header<br>
 * .ya-section-description - section description (all levels)<br>
 * .ya-section-footnote - section footnote (all levels)
 */
public class Section extends Composite {

  protected String style = "ya-section";
  private Widget rootWidget;
  private Label headerL;
  private String description;
  private String footnote;
  private HTML htmlDescription;
  private HTML htmlFootnote;
  private Widget content;
  private boolean collapsible = false;
  private boolean collapsed = false;

  public Section() {
    this(null);
  }

  public Section(String header) {
    this(header, false);
  }

  public Section(String header, boolean collapsible) {
    this.collapsible = collapsible;
    if (collapsible)
      rootWidget = new DisclosurePanel(header);
    else {
      rootWidget = new VerticalPanel();
      if (header != null) {
        headerL = new Label(header);
        headerL.setStyleName("ya-section-header");
        ((VerticalPanel) rootWidget).add(headerL);
      }
    }
    rootWidget.setWidth("100%");
    initWidget(rootWidget);
  }

  /**
   * only for non-collapsible header
   */
  public void setHeader(String header) {
    if (collapsible)
      return;
    headerL.setText(header);
  }

  /**
   * Renders the widget. This must be called for the widget to be rendered. Must
   * be called after content has been added.
   */
  private void renderUI() {
    VerticalPanel contentVP = null;
    if (collapsible) {
      DisclosurePanel rootDP = (DisclosurePanel) rootWidget;
      rootDP.setOpen(!collapsed);
      contentVP = new VerticalPanel();
      rootDP.setContent(contentVP);
    } else {
      contentVP = (VerticalPanel) rootWidget;
    }

    setStyleName(style);

    if (description != null) {
      Label descL = new Label(description);
      descL.addStyleName("ya-section-description");
      contentVP.add(descL);
    }

    if (htmlDescription != null) {
      htmlDescription.addStyleName("ya-section-description");
      contentVP.add(htmlDescription);
    }

    if (content != null)
      contentVP.add(content);

    if (footnote != null) {
      Label footnoteL = new Label(footnote);
      footnoteL.addStyleName("ya-section-footnote");
      contentVP.add(footnoteL);
    }

    if (htmlFootnote != null) {
      htmlFootnote.addStyleName("ya-section-footnote");
      contentVP.add(htmlFootnote);
    }

  }

  /**
   * Set content widget of the section. This will also render the widget.
   */
  public void setContent(Widget content) {
    this.content = content;
    renderUI();
  }

  /**
   * Sets if the section is collapsible or not
   */
  public void setCollapsed(boolean collapsed) {
    this.collapsed = collapsed;
  }

  /**
   * Sets description
   */
  public void setDescription(String description) {
    this.description = description;
  }

  /**
   * Sets HTML description
   */
  public void setDescription(HTML htmlDescription) {
    this.htmlDescription = htmlDescription;
  }

  /**
   * Sets footnote
   */
  public void setFootnote(String footnote) {
    this.footnote = footnote;
  }

  /**
   * Sets HTML footnote
   */
  public void setFootnote(HTML htmlFootnote) {
    this.htmlFootnote = htmlFootnote;
  }

}
